package jmind.core.mongodb;

import java.io.File;
import java.io.IOException;
import java.util.List;

import jmind.core.mongodb.MongoPojo.Field;
import jmind.base.util.DataUtil;
import jmind.base.util.IOUtil;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import com.google.common.collect.Lists;

/**
 * 根据配置文件，自动生成mongo pojo
 * @author weibo-xie
 * 2013-2-4
 */
public class MongoCodeGen {

    /**
     * @param args
     */
    public static void main(String[] args) {
        if (args.length == 2) {
            generate(args[0], args[1]);
        } else {
            generate("/Users/wbxie/work/workspace/chineseall/jmind-core/doc/gen/app.xml", "/data/app/");
        }

    }

    public static void generate(String file, String path) {
        List<MongoPojo> list = parse(file);
        for (MongoPojo pojo : list) {
            String str = builder(pojo);
            IOUtil.writerText(path + pojo.getClassName() + ".java", str, false);
        }
    }

    public static String builder(MongoPojo pojo) {
        StringBuilder sb = new StringBuilder("package " + pojo.getPackageName() + " ;");
        sb.append("\n");
        sb.append("import com.mongodb.BasicDBObject; \n");
        sb.append("import org.bson.types.ObjectId;");
        sb.append("\n");
        sb.append("public class " + pojo.getClassName() + "   extends BasicDBObject {");
        sb.append("\n");
        for (Field f : pojo.getFields()) {
            if (!DataUtil.isEmpty(f.getDesc())) {
                sb.append("//" + f.getDesc());
                sb.append("\n");
            }
            sb.append(" private  String  " + f.getName() + "=\"" + f.getValue() + "\" ;");
            sb.append("\n");
        }
        for (Field f : pojo.getFields()) {
            // set
            sb.append(" public  " + pojo.getClassName() + "  " + f.getName() + "(" + f.getType() + "   val){ ");
            sb.append("\n");
            sb.append("this.put(" + f.getName() + ", val);");
            sb.append("\n");
            sb.append("return this;");
            sb.append("\n");
            sb.append("}");
            sb.append("\n");
            //  get
            sb.append(" public  " + f.getType() + "  " + f.getName() + "(){ ");
            sb.append("\n");
            if ("String".equalsIgnoreCase(f.getType())) {
                sb.append("return  this.getString(" + f.getName() + ");");
            } else if ("ObjectId".equalsIgnoreCase(f.getType())) {
                sb.append("return  this.getObjectId(" + f.getName() + ");");
            } else if ("Integer".equalsIgnoreCase(f.getType()) || "int".equals(f.getType())) {
                sb.append("return  this.getInt(" + f.getName() + ",0);");
            } else if ("Long".equalsIgnoreCase(f.getType())) {
                sb.append("return  this.getLong(" + f.getName() + ",0);");
            } else {
                sb.append("return  (" + f.getType() + ")this.get(" + f.getName() + ");");
            }

            sb.append("\n");
            sb.append("}");
            sb.append("\n");
        }
        return sb.append("\n}").toString();
    }

    public static List<MongoPojo> parse(String file) {
        List<MongoPojo> list = Lists.newArrayList();
        try {
            Document doc = Jsoup.parse(new File(file), "UTF-8");
            String packageName = doc.select("package").attr("name");
            Elements classes = doc.select("class");
            MongoPojo pojo = null;
            for (Element c : classes) {
                String cName = DataUtil.firstLetterToUpperCase(c.attr("name"));
                pojo = new MongoPojo();
                pojo.setPackageName(packageName);
                pojo.setClassName(cName);
                Elements fields = c.select("field");

                for (Element f : fields) {
                    pojo.setField(f.attr("name"), f.attr("value"), f.attr("type"), f.attr("desc"));
                }
                list.add(pojo);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return list;

    }

}
